_import("java.time.LocalDateTime")
//验证码错误次数阈值，超过此值不在进行重试
var CAPTCHA_TIMES_THRESHOLD = 2

var urls = {
    LOGIN_URL: "https://sbank.hxb.com.cn/easybanking/jsp/indexComm.jsp",
    //账户信息                                                                                                                             randomTokenVerifyTag=ae210eabcaf87cc7dfda5a6af80d10a6&verifyCodeBackUriTag=%2Fjsp%2Fsafeguard%2Ftokeninvalid.jsp&accountName=1
    //USER_DETAIL_URL: "https://sbank.hxb.com.cn/easybanking/PCreditAcctInfoQuery/PCreditAcctInfoQueryAction.do?actionType=redirect     &randomTokenVerifyTag=ea07a2eb4e78609e0f9fe9cb69eadb9a&verifyCodeBackUriTag=/jsp/safeguard/tokeninvalid.jsp&accountName=1",
    USER_DETAIL_URL: "https://sbank.hxb.com.cn/easybanking/PCreditAcctInfoQuery/PCreditAcctInfoQueryAction.do?actionType=redirect",
    //卡片信息
    CARD_DETAIL_URL: "https://sbank.hxb.com.cn/easybanking/PAccountInfoDetailsQuery/PAccountInfoDetailsQueryAction.do?actionType=entry&OLN_top_activeNode=top11&OLN_top11side10_activeNode=top10side30&sideMenuBar=OLN_top11side10",
    //账单详细中的下一页
    BILLDETAIL_NEXT_PAGE_URL: "https://sbank.hxb.com.cn/easybanking/jsp/pcredittabquery/pcredittabquery-pcredit-tab-query-query-form-view.jsp?d-2693382-p=%s",
    //账单详细
    BILLDETAIL_URL :  "https://sbank.hxb.com.cn/easybanking/PCreditTabQuery/FormParedirectAction.do?actionType=redirect",
    // BILLDETAIL_URL: "https://sbank.hxb.com.cn/easybanking/PCreditTabQuery/FormParedirectAction.do?actionType=redirect &randomTokenVerifyTag=22d2634345fce64ccd5d08a974ca6ce5&verifyCodeBackUriTag=/jsp/safeguard/tokeninvalid.jsp&accountName=1&billYearMonYear=%s&billYearMonMonth=%s",

    //BILLUNDONE_URL: "https://sbank.hxb.com.cn/easybanking/PCreditBusiDetailsWithoutTabQuery/FormParedirectAction.do?actionType=redirect&randomTokenVerifyTag=18b67d596b94598aec7321a6710a0ad9&verifyCodeBackUriTag=jsp/safeguard/tokeninvalid.jsp&randomTokenVerifyTag=9fc24b2a82571036a18b04cdf9768dd9&verifyCodeBackUriTag=/jsp/safeguard/tokeninvalid.jsp&accountName=1",
    BILLUNDONE_URL :"https://sbank.hxb.com.cn/easybanking/PAccountQueryAccountDetails/FormParedirectAction.do?actionType=redirect",

    //登录成功url
    LOGIN_SUCCESS_URL: "https://sbank.hxb.com.cn/easybanking/PAccountWelcomePage/FormParedirectAction.do?actionType=entry",

    BILL_INSTALLMENT_URL: "https://sbank.hxb.com.cn/easybanking/PCreditInstalmentQuery/FormParedirectAction.do?actionType=redirect",


    //借记卡
    USER_DETAIL_URLS: "https://sbank.hxb.com.cn/easybanking/PAccountInfoDetailsQuery/PAccountInfoDetailsQueryAction.do?actionType=entry&OLN_top_activeNode=top11&OLN_top11side10_activeNode=top10side30&sideMenuBar=OLN_top11side10",
    CARD_DETAIL_URLS: "https://sbank.hxb.com.cn/easybanking/PAccountCardInfoQuery/PAccountCardInfoQueryAction.do?actionType=entry&OLN_top_activeNode=top11&OLN_top11side10_activeNode=top10sideC0&sideMenuBar=OLN_top11side10",
    BILLDETAIL_URLS: "https://sbank.hxb.com.cn/easybanking/PAccountQueryAccountDetails/FormParedirectAction.do?actionType=redirect",
    USER_DETAIL_URLM: "https://sbank.hxb.com.cn/easybanking/PAccountQueryAccountDetails/PAccountQueryAccountDetailsAction.do?actionType=entry&OLN_top_activeNode=top11&OLN_top11side10_activeNode=top10side40&sideMenuBar=OLN_top11side10",
    BILL_INSTALLMENT_URLS: "https://sbank.hxb.com.cn/easybanking/PCreditInstalmentQuery/PCreditInstalmentQueryAction.do?actionType=entry&OLN_top_activeNode=top64&OLN_top64side10_activeNode=top64side20&sideMenuBar=OLN_top64side10",
    USER_DETAIL_URLL: "https://sbank.hxb.com.cn/easybanking/PAccountInfoDetailsQuery/SFormPaconfirmationAction.do?actionType=confirm",
    USER_BASE_URL: "https://sbank.hxb.com.cn/easybanking/PAccountMyAccount/ListPageGetSaveBalanceAction.do?actionType=link",
    BILL_DEPOSITS_URLS: "https://sbank.hxb.com.cn/easybanking/PSaveSavingacctToTerm/PSaveSavingacctToTermAction.do?actionType=entry&OLN_top_activeNode=top31&OLN_top31side10_activeNode=top31side10&sideMenuBar=OLN_top31side10"
}

var openTime = "";
var dateBill = "";//账单日
var creditSdf = new SimpleDateFormat("YYYY-MM");//信用卡
var sdf = new SimpleDateFormat("yyyy-MM-dd");
var indexHtml = "";
var isError = false;
var time = 0;
var retryTime = 0;
var getDetailBillByDateNew = Pattern.compile("\\d*条");


var v4_hxb_java_funcs = {
    openHomePage : function(){
        //访问首页
        get("https://sbank.hxb.com.cn/easybanking/jsp/indexComm.jsp");
        var indexHtml = luaFuncs.getHtml();
        //页面不为空
        context.put("indexHtml", indexHtml)
        storeDataToFile(context, indexHtml, "index.html")
    },
    checkProxyAvailable: function () {
        var indexHtml = context.get("indexHtml")
        if(StringUtils.isBlank(indexHtml)) {
            return false
        }
        var doc = Jsoup.parse(indexHtml)
        logger.info("任务【 {} 】标题='{}'", context.get(LUA_TASK_KEY), doc.select("title").text())
        if(equals("500 Internal Server Error",doc.select("title").text())){
            throwBankExceptionByErrorCodeAndCustomMessage(BALO_99605_25,"银行内部系统错误")
        }


        logger.info("任务【 {} 】id='div1'的元素个数{}", context.get(LUA_TASK_KEY), doc.select("#div1").size())

        return equals(doc.select("title").text(), "华夏银行 - 个人登录页") && doc.select("#div1").size() > 0

    },
    checkTargetWebsiteAvailable: function(){ return true },
    checkControlAvailable:function (){ return luaFuncs.checkControlAvailable()},
    login: function () {
        show();
        var clickElementId = equals(USERNAME, LoginType.stringToLoginType(context.get(LUA_TASK_LOGIN_TYPE))) ? "divli1" : "divli2"
        logger.info("任务【 {} 】点击元素ID {}", context.get(LUA_TASK_KEY), clickElementId)
        click_by_id(clickElementId)

        var  passwordOld = context.get(LUA_TASK_TOKEN);
        logger.info("{},原始密码的长度:{}",context.get(LUA_TASK_KEY),passwordOld.length());

        var  passwordNew =  passwordOld.replaceAll("\\s*","");
        logger.info("{},密码去掉所有空格的长度:{}",context.get(LUA_TASK_KEY),passwordNew.length());

        if(passwordOld.length() != passwordNew.length()){
            throwBankExceptionByErrorCodeAndCustomMessage(BALO_22001_10,"用户名或密码错误，请重新输入");
        }
        var inputResult = luaFuncs.inputUPAndGetOperationResult(getLoginParams(context)[0],passwordOld , clickElementId);
        hide();

        var isPasswordCorrectFunc = function(inputResult) {
            return Boolean.valueOf(inputResult)
        }

        var getPasswordErrorMsgFunc = function(inputResult) {
            return "密码因控件输入错误"
        }

        assertTrueOrThrowException(inputResult, isPasswordCorrectFunc, getPasswordErrorMsgFunc)

        // 验证码　　　一般出现验证码　只能是连续输错密码时　　再不杀进程的情况下　会出现图片验证码
        // if (equals(luaFuncs.check_is_img(), "true")) {
        //     var img = get_image_by_id("validateNoImage");
        //     context.put(TASK_IMG_PATH, img);
        //
        //     context.put(TASK_IMG_REGEX,"[0-9a-zA-Z]{4}");
        //     var imgCode = waitImgCodeBySecondsByJs(context, 60, true, 3);
        //
        //     var msg = set_input_text_by_id("validateNo", imgCode.toLowerCase());
        //     logger.info("{},输入验证码返回的信息:{}",context.get(LUA_TASK_KEY),msg);
        // }

        logger.info("{}, 点击登录按钮", context.get(LUA_TASK_KEY));
        var loginResult = luaFuncs.click_by_name("qy_sut");
        logger.info("{}, 登录成功返回的结果:{}", context.get(LUA_TASK_KEY),loginResult);

        //check开始: 检查图片验证码位数是否正确
        var isLoginCorrectFunc = function(loginResult) {
            return StringUtils.equals(loginResult, "OK")
        }

        var getLoginErrorMsgFunc = function(loginResult) {
            return loginResult
        }


         assertTrueOrThrowException(loginResult, isLoginCorrectFunc, getLoginErrorMsgFunc)
           /*var cookies = luaFuncs.getLoginCookie();
            context.put("cookies", cookies);*/
    },
    crawl: function () {
       /* var header = new LinkedHashMap();
            header.put("Cookie", context.get("cookies"));
            header.put("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko");
         context.put("header",header);
        var cardList = RequestUtil.get(urls.USER_DETAIL_URLS, null, header);*/

        var htmls = ajax_get(urls.USER_DETAIL_URLS);
        storeDataToFile(context, htmls, "cardList.html");
        var doc = Jsoup.parse(htmls);
        var tableElement = doc.getElementById("accountDetailQueryDisplayVBList_row");
        if (tableElement == null) {
            throw new BankException(BALO_22101_10, "尚未注册或无此用户");
        }
        var tbodys = tableElement.select("tbody");

        var trs1 = tbodys.select("tr");
        var list=new ArrayList();
        for (var q = 0; q < trs1.size(); q++) {
            var tds = trs1.get(q).select("td");
            var currentType = tds.get(4).text();
            logger.info("{},类型:{},长度:{}", context.get(LUA_TASK_KEY), currentType, trs1.size());
            if (equals(currentType, "华夏信用卡")) {
                logger.info("任务taskKey = {}, 开始抓取信用卡", context.get(LUA_TASK_KEY));
                creditCrawl(q, tds,list);
                break;
            }

            if (equals(currentType, "活期")) {
                logger.info("任务taskKey = {}, 开始抓取借记卡", context.get(LUA_TASK_KEY));
                debitCrawl(q, tds, htmls,list);
            }
        }

        context.put(ALL_DATA, list);

    },
    exitLogin: function () {}

}

function debitCrawl(q, tds, htmls,list) {
    // 获取首页源码
    var indexPage = get_html();
    storeDataToFile(context, indexPage, "indexPage.html");
    if (indexPage.contains("代理服务器没有响应")) {
        logger.info("任务:{},首页信息：代理服务器没有响应", context.get(LUA_TASK_KEY));
        return;
    }

    // 卡号
    var fullCardNum = tds.get(2).text();
    // 卡号后四位
    var card_num = fullCardNum.substring(fullCardNum.length() - 4, (fullCardNum.length()));
    logger.info("次数:{},借记卡卡号后四位:{}", q, card_num);
    // 声明存储对象
    var creditCardAllData = new CreditCardAllData();
    // 声明存储金额列表
    var deposits = new ArrayList();
    // 声明账单列表
    var bills = new ArrayList();

    creditCardAllData.setDeposits(deposits);

    var depositHtml =  ajax_get("https://sbank.hxb.com.cn/easybanking/PAccountInfoDetailsQuery/PAccountInfoDetailsQueryAction.do?actionType=confirm&selected=0")
    storeDataToFile(context, depositHtml, q + "_deposits_1.html");
    try {
        getDetailBillByDeposit(depositHtml, deposits, card_num,
            creditCardAllData);
    } catch (e) {
        logger.info("{},借记卡的存储信息抓取异常:{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }


    // 基本数据的填充
    getBasicNeedInfoDebit(creditCardAllData, card_num, q, deposits);

    var json = ajax_get(urls.USER_DETAIL_URLM);
    storeDataToFile(context, json, q + "_baseHtml_1.html");
    var map = new HashMap();
    var baseDoc = Jsoup.parse(json);
    var select = baseDoc.getElementById("paredirectCardNo");
    var options;
    if(select!= null){
         options = select.getElementsByTag("option");
    }

    for each(var option in options){
        var cardT = option.text();
        if (cardT.endsWith(card_num)) {
            var value = option.attr("value");
            logger.info("卡号:{}，option选项值:{}", card_num, value);
            map.put("value", value);
        }
    }


    // 获取近6月的账单查询
    var calendars = Calendar.getInstance();
    var current_year = calendars.get(Calendar.YEAR);
    current_year = Integer.parseInt(current_year);
    var current_month = calendars.get(Calendar.MONTH) + 1; // calendar.get(Calendar.MONTH)返回值得第一个月为0，所以+1。
    current_month = Integer.parseInt(current_month);
    var current_day = calendars.get(Calendar.DAY_OF_MONTH);
    current_day = Integer.parseInt(current_day);

    var calendar = Calendar.getInstance();
    for (var i = 0; i < 6; i++) {
        var year = calendar.get(Calendar.YEAR);
        year = Integer.parseInt(year);
        var month = calendar.get(Calendar.MONTH) + 1; // calendar.get(Calendar.MONTH)返回值得第一个月为0，所以+1。
        month = Integer.parseInt(month);
        var first = calendar.getActualMinimum(Calendar.DAY_OF_MONTH); // 获取本月最小天数
        first = Integer.parseInt(first);
        var last = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取本月最大天数
        last = Integer.parseInt(last);

        try {
            getDetailBillByDateNews(creditCardAllData, year, month,
                bills, current_year, current_month, current_day,
                first, last, i, map, card_num, q);
        } catch (e) {
            logger.info("{},华夏借记卡账单{}解析错误,{}", context.get(LUA_TASK_KEY), month, e);
            statCaughtException(context, e);
        }
        calendar.add(Calendar.MONTH, -1);
    }
    creditCardAllData.setBills(bills);
    list.add(creditCardAllData);
}

/**
 * 借记卡的存储信息 ===活期和定期
 * @param depositHtml
 * @param deposits
 * @param card_num
 * @param creditCardAllData
 */
function getDetailBillByDeposit(depositHtml, deposits, card_num, creditCardAllData) {
    var doc = Jsoup.parse(depositHtml);
    var name = doc.select("body > div.wrap > div.content > div.main_content > div.transaction_content > div > table.inputStyleTable > tbody > tr:nth-child(1) > td.field").text();
    creditCardAllData.setNameOnCard(name);
    var deposit = new CreditCardTimeDeposit();
    var tableElement = doc.select("[class='inputStyleTable']").get(0);
    var tds = tableElement.getElementsByTag("tr");
    var balance = tds.get(6).select("td").get(1).text().replaceAll(",", "");
    var currency_type = tds.get(2).select("td").get(1).text();
    var deposit_date = tds.get(12).select("td").get(1).text();
//		String due_date = tds.get(5).select("td").get(1).text();
    var interest = tds.get(4).select("td").get(1).text();
    var deposit_type = tds.get(3).select("td").get(1).text();
    deposit.setBalance(new BigDecimal(balance));
    deposit.setCurrencyType(CreditResultUtil.convertCurr(currency_type));
    deposit.setDepositDate(yyyy_MM_dd_PARSER.parse(deposit_date));
    deposit.setDueDate(null);
    var replaceAll1 = interest.replaceAll("%", "");
    openTime = tds.get(12).select("td").get(1).text();
    var newInterest = String.format("%.3f", Double.parseDouble(replaceAll1) / 100);
    deposit.setInterest(new BigDecimal(newInterest));
    deposit.setPeriod(null);
    deposit.setPeriodUnit("");
    deposit.setDepositType(deposit_type);
    deposits.add(deposit);
    creditCardAllData.setOpenTime(yyyy_MM_dd_PARSER.parse(openTime));
}

/**
 * 借记卡基本数据的填充
 *
 * @param creditCardAllData
 * @param card_num
 * @param j
 * @param deposits
 * @throws Exception
 */
function getBasicNeedInfoDebit(creditCardAllData, card_num, j, deposits) {
    creditCardAllData.setBankName("华夏银行");
    creditCardAllData.setCardNum(card_num);
    creditCardAllData.setCardId(UUID.randomUUID().toString());// 无卡号,使用uuid生成
    creditCardAllData.setCardType("借记卡");
    creditCardAllData.setCashLimit(null);
    creditCardAllData.setCashBalance(null);
    creditCardAllData.setCreditLimit(null);
    /**
     * 主要是借记卡的余额
     */
    try {
        var htm = ajax_get(urls.USER_BASE_URL);
        storeDataToFile(context, htm, j + "_cardBalance_1.html");
        var docm = Jsoup.parse(htm);
        var trs = docm.select("[class='even']");
        for (var i = 0; i < trs.size(); i++) {
            var cardNum = trs.get(i).select("td").get(2).text();
            if (cardNum.endsWith(card_num)) {
                var balance = MyStringUtils.GetText(trs.get(i).select("td").get(3).text(), "\\d+.\\d+").replaceAll(",", "");
                creditCardAllData.setBalance(new BigDecimal(balance));
            }
        }
    } catch (e) {
        logger.info("{},借记卡余额解析异常：{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
    /*
     * 开户行
     */
    var html = ajax_get(urls.USER_DETAIL_URLS);
    storeDataToFile(context, html, j + "_cardOpenBank_1.html");
    try {
        parseUserInfos(html, creditCardAllData, card_num);
    } catch (e) {
        logger.info("{},借记卡开户行解析异常：{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }

    /*
     * 借记卡卡片信息详细页面(序号 卡号 起息日期 状态 卡类别)
     */
    html = ajax_get(urls.CARD_DETAIL_URLS);
    storeDataToFile(context, html, j + "_cardFullCardNum.html");
    // 卡片信息解析
    try {
        parseCardInfosDebit(html, creditCardAllData, card_num, deposits);
    } catch (e) {
        logger.info("{},借记卡卡号解析异常：{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
}

/**
 * 借记卡的账单流水
 * @param creditCardAllData
 * @param year
 * @param month
 * @param bills
 * @param current_year
 * @param current_month
 * @param current_day
 * @param first
 * @param last
 * @param i
 * @param map
 * @param card_num
 * @param j
 */
function getDetailBillByDateNews(creditCardAllData, year, month, bills, current_year, current_month, current_day, first, last, i, map, card_num, j) {
    logger.info("{},华夏银行抓取年月={}", context.get(LUA_TASK_KEY), year + "_" + month);

    var shopping_sheets = new ArrayList();// 消费记录

    var postdata = getPostData(year, month, current_year, current_month, current_day, first, last, map);

    var html = ajax_post(urls.BILLDETAIL_URLS, postdata);
    storeDataToFile(context, html, j + "_billdetail" + year + "_" + month
        + "_" + i + ".html");
    if (html.contains("代理服务器没有响应")) {
        logger.info("任务:{},{}账单明细信息：代理服务器没有响应", context.get(LUA_TASK_KEY), year + "-" + month);
        return;
    }
    //获取BillAllData
    var billAllData = getBillAllData(year, month);

    var doc = Jsoup.parse(html);
    var trs = doc.select("[class='inputStyleTable']");
    var cardNum = trs.get(0).select("td").get(3).text();
    cardNum = cardNum.substring(cardNum.length() - 4, (cardNum.length()));
    var export_xml = doc.select("span[class=export xml]");
    logger.info("导出xml的长度:{}", export_xml.size());
    if (export_xml.size() != 0) {
        var span = export_xml.get(0);
        var downLoadUrl = span.parent().attr("href");
        logger.info("开始点击导出XML的方式的href:{}",
            downLoadUrl);
        if (StringUtils.isNotBlank(downLoadUrl)) {
            Thread.sleep(2000);
            var result = ajax_get("https://sbank.hxb.com.cn/"
                + downLoadUrl);
            storeDataToFile(context, result, j + "_billdetails" + year + "_" + month + "_" + i + ".xml");
            var docm = Jsoup.parse(result);
            logger.info("开始解析{}月份帐单", year + "_" + month);
            var rows = docm.select("row");
            logger.info("有{}行", rows.size());
            for each(var row in rows){
                var exp = new Expense();
                var columns = row.select("column");
//					logger.info("有{}列",columns.size());
                exp.setId(UUID.randomUUID().toString());
                exp.setOrderIndex(Long.parseLong(columns.get(0).text()));
                exp.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(columns.get(1).text() + " 00:00:00"));
                exp.setPostDate(null);
                exp.setTransMethod(columns.get(2).text());
                exp.setCurrencyType(CreditResultUtil.convertCurr(columns
                    .get(3).text()));
                var money = columns.get(4).text().replaceAll(",", "");
                if (StringUtils.isBlank(money)) {
                    var amount_money = columns.get(5).text().replaceAll(",", "");
                    exp.setAmountMoney(new BigDecimal(amount_money));
                } else {
                    exp.setAmountMoney(new BigDecimal(money).negate());
                }
                exp.setBalance(new BigDecimal(columns.get(6).text().replaceAll(",", "")));
                exp.setOppositeCardNo(NullToString(columns.get(7)));
                exp.setNameOnOppositeCard(NullToString(columns.get(8)));
                exp.setOppositeBank(NullToString(columns.get(9)));
                exp.setDescription(columns.get(11).text());
                exp.setCategory(CategoryUtil.getDebitCategory(columns.get(11).text(), columns.get(5).text().replaceAll(",", "")));
                exp.setRemark("");
                exp.setTransAddr("");
                exp.setTransMethod("");
                exp.setTransChannel("");
                exp.setCardNum(cardNum);
                shopping_sheets.add(exp);
            }
        }
    }
    billAllData.setShoppingSheets(shopping_sheets);
    bills.add(billAllData);
}


function getPostData(year, month, current_year,
                     current_month, current_day, first, last, map) {
    var postdata = new HashMap();
    postdata.put("account", "1");
    postdata.put("autoEdate", "");
    postdata.put("autoSdate", "");
    postdata.put("billYearMonMonth", getYearOrDayString(month));
    postdata.put("billYearMonYear", getYearOrDayString(year));
    postdata.put("busiType", "0");
    postdata.put("cardNo", map.get("value"));
    postdata.put("db_current_time_day", getYearOrDayString(current_day));
    postdata.put("db_current_time_month", getYearOrDayString(current_month));
    postdata.put("db_current_time_year", getYearOrDayString(current_year));
    postdata.put("maxAmt", "");
    postdata.put("minAmt", "");
    postdata.put("queryDateFlag", "");
    if (month == current_month) {
        postdata.put("queryEndDateDay", getYearOrDayString(current_day));
    } else {
        postdata.put("queryEndDateDay", getYearOrDayString(last));
    }
    postdata.put("queryEndDateMonth", getYearOrDayString(month));
    postdata.put("queryEndDateYear", getYearOrDayString(year));
    postdata.put("queryMode", "1");
    postdata.put("queryStrDateDay", getYearOrDayString(first));
    postdata.put("queryStrDateMonth", getYearOrDayString(month));
    postdata.put("queryStrDateYear", getYearOrDayString(year));
    postdata.put("randomTokenVerifyTag", "4b302ff60657a9507e155ba37161b1de");
    postdata.put("sortFlag", "0");
    postdata.put("verifyCodeBackUriTag", "/jsp/safeguard/tokeninvalid.jsp");
    return postdata;
}

function getBillAllData(year, month) {
    var billAllData = new BillAllData();
    billAllData.setBankName("华夏银行");
    billAllData.setBillId(UUID.randomUUID().toString());
    var installments = new ArrayList();
    billAllData.setInstallments(installments);

    billAllData.setBillMonth(year + "-" + getYearOrDayString(month));
    billAllData.setBillType("");
    billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(year + "-" + getYearOrDayString(month) + "-01"));

    // 以下数据页面无
    billAllData.setMinPayment(null);
    billAllData.setInterest(null);
    billAllData.setLastBalance(null);
    billAllData.setLastPayment(null);
    billAllData.setNewCharges(null);
    // 信用额度相关
    billAllData.setNewBalance(null);
    billAllData.setCreditLimit(null);
    billAllData.setCashLimit(null);
    // 美元相关---------先暂且设置为0
    billAllData.setUsdCashLimit(null);
    billAllData.setUsdCreditLimit(null);
    billAllData.setUsdInterest(null);
    billAllData.setUsdLastBalance(null);
    billAllData.setUsdLastPayment(null);
    billAllData.setUsdMinPayment(null);
    billAllData.setUsdNewBalance(null);
    billAllData.setUsdNewCharges(null);
    return billAllData;
}

function NullToString(element) {
    if (element == null) {
        return "";
    }
    return element.text();
}

/**
 * 只做了一个开户行
 * @param html
 * @param creditCardAllData
 * @param card_num2
 */
function parseUserInfos(html, creditCardAllData, card_num2) {
    var doc = Jsoup.parse(html);
    var trs = doc
        .getElementById("accountDetailQueryDisplayVBList_row").select(
            "tbody").select("tr");
    for (var j = 0; j < trs.size(); j++) {
        var tds = trs.get(j).select("td");
        // 卡号
        var fullCardNum = tds.get(2).text();
        if (fullCardNum.endsWith(card_num2)) {
            var open_bank = tds.get(5).text();
            creditCardAllData.setOpenBank(open_bank);
        }
    }
}

/**
 * 只做了一个得到全部卡号
 * @param html
 * @param creditCardAllData
 * @param card_num
 * @param deposits
 */
function parseCardInfosDebit(html, creditCardAllData, card_num, deposits) {
    var docs = Jsoup.parse(html);
    var trs = docs.getElementById("cardInfoTableList_row").select(
        "tbody").select("tr");
    for (var i = 0; i < trs.size(); i++) {
        var full_card_num = trs.get(i).select("td").get(1).text();
        if (full_card_num.endsWith(card_num)) {
            creditCardAllData.setFullCardNum(full_card_num);
        }
    }
}


function getYearOrDayString(num) {
    var mon = "";
    if (String.valueOf(num).length() == 1) {
        mon = "0" + String.valueOf(num);
    } else {
        mon = String.valueOf(num);
    }
    return mon;
}

/**
 * 信用卡
 * @throws Exception
 */
function creditCrawl(q, tds,list) {
    // 获取首页源码
    var indexPage = get_html();
    if (indexPage.contains("代理服务器没有响应")) {
        logger.info("任务:{},账单信息：代理服务器没有响应", context.get(LUA_TASK_KEY));
    }
    storeDataToFile(context, indexPage, "indexPage.html");

    // 卡号
    var fullCardNum = RegexUtils.GetText(tds.get(1).text(), "\\d*");
    logger.info("次数:{},信用卡完整卡号:{}", q, fullCardNum);
    //开户行
    var open_bank = tds.get(5).text();
    // 卡号后四位
    var card_num = fullCardNum.substring(fullCardNum.length() - 4, (fullCardNum.length()));
    // 声明存储对象
    var creditCardAllData = new CreditCardAllData();
    creditCardAllData.setOpenBank(open_bank);
    // 声明账单列表
    var bills = new ArrayList();
    creditCardAllData.setBills(bills);
    var creditCardTimeDeposits = new ArrayList();
    creditCardAllData.setDeposits(creditCardTimeDeposits);

    // 基本数据的填充
    getBasicNeedInfo(creditCardAllData, q, card_num);


    /**
     * 未出账单和已出账单需要的参数
     * @type {HashMap}
     */
    var undoneAndDoneBeforMap = new HashMap();
    var undoneAndDoneBeforHtml =  ajax_get("https://sbank.hxb.com.cn/easybanking/PAccountQueryAccountDetails/PAccountQueryAccountDetailsAction.do?actionType=entry&OLN_top_activeNode=top11&OLN_top11side10_activeNode=top10side40&sideMenuBar=OLN_top11side10")
     storeDataToFile(context, undoneAndDoneBeforHtml,  "undoneAndDoneBeforHtml.html");

    var undoneAndDoneBeforDoc = Jsoup.parse(undoneAndDoneBeforHtml);
    var randomTokenVerifyTag  = undoneAndDoneBeforDoc.select("#randomTokenVerifyTag").attr("value");
    logger.info(randomTokenVerifyTag);
    var verifyCodeBackUriTag =  undoneAndDoneBeforDoc.select("#verifyCodeBackUriTag").attr("value");
    logger.info(verifyCodeBackUriTag)

    undoneAndDoneBeforMap.put("randomTokenVerifyTag",randomTokenVerifyTag);
    undoneAndDoneBeforMap.put("verifyCodeBackUriTag",verifyCodeBackUriTag);

    /**
     * 就是为了寻找账单日
     */
    var calendarBillDate = Calendar.getInstance();
    for (var i = 0; i < 6; i++) {
        var year = calendarBillDate.get(Calendar.YEAR);
        year = Integer.parseInt(year);
        var month = calendarBillDate.get(Calendar.MONTH) + 1; // calendar.get(Calendar.MONTH)返回值得第一个月为0，所以+1。
        month = Integer.parseInt(month);
        var monStr = "";
        if(month < 10){
            monStr = "0" + month;
        }
        dateBill = getBillDateFromDone(year, monStr,undoneAndDoneBeforMap);
        if (dateBill !== "") {
            dateBill = dateBill.substring(8, 10);
            logger.info("账单日:{}", dateBill);
            break;
        }
        calendarBillDate.add(Calendar.MONTH, -1);
    }


    // 获取近7月的账单查询
    var recentMonthList = getRecentMonth();
    logger.info("{},月份的集合长度:{}", context.get(LUA_TASK_KEY) , recentMonthList.size());
    if (recentMonthList.size() <= 0) {
        logger.info("{},又没有账单日又没有消费,页面就是空的",context.get(LUA_TASK_KEY));
        var calendar = Calendar.getInstance();
        for (var i = 0; i < 6; i++) {
            var year = calendar.get(Calendar.YEAR);
            year = Integer.parseInt(year);
            var mon = calendar.get(Calendar.MONTH) + 1; // calendar.get(Calendar.MONTH)返回值得第一个月为0，所以+1。
            mon = Integer.parseInt(mon);
            var month = "";
            if (String.valueOf(mon).length() == 1) {
                month = "0" + String.valueOf(mon);
            } else {
                month = String.valueOf(mon);
            }
            var billAllData = new BillAllData();
            billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(year + "-" + month + "-05"));
            billAllData.setBillMonth(year + "-" + month);
            billAllData.setBankName("华夏银行");
            billAllData.setBillId(UUID.randomUUID().toString());// UUID随机生成
            billAllData.setBillType("DONE");// 无数据
            billAllData.setNewBalance(null);
            billAllData.setMinPayment(null);
            billAllData.setLastBalance(null);
            billAllData.setLastPayment(null);
            billAllData.setNewCharges(null);
            billAllData.setInterest(null);
            billAllData.setUsdCashLimit(null);
            billAllData.setUsdCreditLimit(null);
            billAllData.setUsdInterest(null);
            billAllData.setUsdLastBalance(null);
            billAllData.setUsdLastPayment(null);
            billAllData.setUsdMinPayment(null);
            billAllData.setUsdNewBalance(null);
            billAllData.setUsdNewCharges(null);
            billAllData.setCashLimit(creditCardAllData.getCashLimit());
            billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
            calendar.add(Calendar.MONTH, -1);
            bills.add(billAllData);
        }
    } else {//集合长度不为0的时候
        for (var i = 0; i < recentMonthList.size(); i++) {

            var openTime =  creditCardAllData.getOpenTime();
            var everyMonthDate =   creditSdf.parse(recentMonthList.get(i));
           if(null != openTime){
               if(everyMonthDate.before(openTime)){
                   continue;
               }
           }

            var year = recentMonthList.get(i).substring(0, 4);
            var month = recentMonthList.get(i).substring(5, recentMonthList.get(i).length());

            try {
                var billAllData = new BillAllData();
                billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(recentMonthList.get(i) + "-" + dateBill));// 账单日
                billAllData.setBillMonth(recentMonthList.get(i));
                billAllData.setBankName("华夏银行");
                billAllData.setBillId(UUID.randomUUID().toString());// UUID随机生成
                billAllData.setBillType("DONE");// 无数据
                billAllData.setUsdCashLimit(null);
                billAllData.setUsdCreditLimit(null);
                billAllData.setUsdInterest(null);
                billAllData.setUsdLastBalance(null);
                billAllData.setUsdLastPayment(null);
                billAllData.setUsdMinPayment(null);
                billAllData.setUsdNewBalance(null);
                billAllData.setUsdNewCharges(null);
                billAllData.setCashLimit(creditCardAllData.getCashLimit());
                billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
                getDetailBillByDateNew123(creditCardAllData, year, month, card_num, q, i, billAllData,undoneAndDoneBeforMap);
                bills.add(billAllData);
            } catch (e) {
                logger.info("{},信用卡抓取已出{}账单异常:{}", context.get(LUA_TASK_KEY), year + "_" + month, e);
                statCaughtException(context, e);
            }
        }
    }

    try {
        getBillUndone(creditCardAllData, bills, card_num, q,undoneAndDoneBeforMap);
    } catch (e) {
        logger.info("{},信用卡抓取未出账单异常:{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
    list.add(creditCardAllData);
}





/**
 * 从当前月开始获取最近的六个月
 * @return
 */
function getRecentMonth() {
    var monthList = new ArrayList();
    var calendar = Calendar.getInstance();
    for (var i = 0; i < 6; i++) {
        var day = calendar.get(Calendar.DAY_OF_MONTH);
        day = Integer.parseInt(day);
        if (dateBill !== "" && dateBill !== null) {
            if (day <= Integer.parseInt(dateBill)) {
                calendar.add(Calendar.MONTH, -1);
                monthList.add(creditSdf.format(calendar.getTime()));
            } else {
                monthList.add(creditSdf.format(calendar.getTime()));
                calendar.add(Calendar.MONTH, -1);
            }
        }
    }
    return monthList;
}

/**
 * 唯一做的一件事就是从已出账单中取出账单日（因为账单日不是单独的页面）
 * @param year
 * @param mon
 */
function getBillDateFromDone(year, mon,undoneAndDoneBeforMap) {
    logger.info("{}，进到获取账单日的方法,月份{}", context.get(LUA_TASK_KEY), year + "-" + mon);
    var map = new HashMap();
        map.put("randomTokenVerifyTag",undoneAndDoneBeforMap.get("randomTokenVerifyTag"));
        map.put("verifyCodeBackUriTag",undoneAndDoneBeforMap.get("verifyCodeBackUriTag"));
        map.put("accountName","1");
        map.put("billYearMonYear",year);
        map.put("billYearMonMonth",mon);
      var html = ajax_post(urls.BILLDETAIL_URL,map);
    storeDataToFile(context, html, year + "-" + mon + "billdate.html");
    var doc = Jsoup.parse(html);
    var tableElements = doc.select("table[class=inputStyleTable]");
    if (tableElements.size() > 0) {
        var accStatements = tableElements.get(0).getElementsByTag("td");
        var strg = accStatements.get(1).text().split(" ");
        var monthDay = strg[0].replaceAll("年", "-").replaceAll("月份", "-") + strg[2].replaceAll("：", "").replaceAll("每月", "").replaceAll("日", "");
        if (StringUtils.isNotBlank(monthDay)) {
            return monthDay;
        }
    }
    return "";
}

/**
 * 信用卡的基本信息
 * @param creditCardAllData
 * @param j
 * @param card_num
 */
function getBasicNeedInfo(creditCardAllData, j, card_num) {
    //var map = new HashMap();
    creditCardAllData.setBankName("华夏银行");
    creditCardAllData.setCardId(UUID.randomUUID().toString());// 无卡号,使用uuid生成
    creditCardAllData.setCardType("信用卡");

    // 账户信息详细信息请求地址
        var balanceMap = new HashMap();
            balanceMap.put("randomTokenVerifyTag","ae210eabcaf87cc7dfda5a6af80d10a6");
            balanceMap.put("verifyCodeBackUriTag","%2Fjsp%2Fsafeguard%2Ftokeninvalid.jsp");
            balanceMap.put("accountName","1");
         var html = ajax_post(urls.USER_DETAIL_URL,balanceMap);

    storeDataToFile(context, html, j + "_cardEdu_1.html");
    parseUserInfo(html, creditCardAllData);


    var htmls = ajax_get(urls.CARD_DETAIL_URL);
    storeDataToFile(context, htmls, j + "_cardFullCardNum_1.html");

      var openTimeHtml = ajax_get("https://sbank.hxb.com.cn/easybanking/PAccountMyAccount/ListPageGetCreditBalanceAction.do?actionType=link3");
       storeDataToFile(context, openTimeHtml, j + "_cardOpenTime_1.html");

    var   openTime = Jsoup.parse(openTimeHtml).select("td.eventd:nth-child(6)").text();
    logger.info("{},开卡时间:{}",context.get(LUA_TASK_KEY),openTime)
    if(!equals("",openTime)){
        creditCardAllData.setOpenTime(yyyy_MM_dd_PARSER.parse(openTime));

    }


    // 卡片信息解析
    parseCardInfo(htmls, creditCardAllData, j, card_num);

}

/**
 * 爬取近六个与的华夏对账单新版
 *
 * @param creditCardAllData
 * @param year
 * @param month
 * @param card_num
 * @param j
 * @throws ParseException
 * @throws IOException
 */
function getDetailBillByDateNew123(creditCardAllData, year, month, card_num, j, q, billAllData,undoneAndDoneBeforMap) {
    logger.info("华夏银行抓取年月={}", year + "_" + month);


    var shopping_sheets = new ArrayList();// 消费记录
    var Installments = new ArrayList();//分期记录

    var map = new HashMap();
        map.put("randomTokenVerifyTag",undoneAndDoneBeforMap.get("randomTokenVerifyTag"));
        map.put("verifyCodeBackUriTag",undoneAndDoneBeforMap.get("verifyCodeBackUriTag"));
        map.put("accountName","1");
        map.put("billYearMonYear",year);
        map.put("billYearMonMonth",month);
    var html = ajax_post(urls.BILLDETAIL_URL,map);
    storeDataToFile(context, html, "" + j + "_bill" + year + month + "_1.html");

    var doc = Jsoup.parse(html);
    var elements = doc.select("div[class^=trading_false]");
    for each(var ele in elements){
        var text = ele.text();
        if (StringUtils.isNotBlank(text)) {
            logger.info("华夏银行抓取：银行响应错误信息，该月停止抓取");
            logger.info(text);
            return;
        }
    }
    // 华夏信用卡对账单
    var tableElements = doc.select("table[class=inputStyleTable]");
    //
    if (tableElements == null || tableElements.size() <= 0) {
        return;
    }
    var accStatements = tableElements.get(0).getElementsByTag("td");
    logger.debug("====华夏信用卡对账单====");
    var strg = accStatements.get(1).text().split(" ");
    var monthDay = strg[0].replaceAll("年", "-").replaceAll("月份", "-") + strg[2].replaceAll("：", "").replaceAll("每月", "").replaceAll("日", "");

    billAllData.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(strg[4].replaceAll(":", "").replaceAll("：", "").trim()));
    // 人民币对账单
    tableElements = doc.select("table[class=table]");
    var rmbTds = tableElements.get(0).getElementsByTag("td");
    // ----------------币种-----------
    var currency = CreditResultUtil.convertCurr(rmbTds.get(0).text().trim());

    // 本期应还金额,即账单金额
    billAllData.setNewBalance(CreditResultUtil.StringToBigDecimal(rmbTds.get(1).text().split(":")[1].replaceAll(",", "")));
    if (q == 0) {
        context.put("newBalance", rmbTds.get(1).text().split(":")[1].replaceAll(",", ""));
    }
    //logger.info("10月份newBalance:----{}",context.get("newBalance"));
    // 最低还款额
    billAllData.setMinPayment(CreditResultUtil.StringToBigDecimal(rmbTds.get(2).text().split(":")[1].replaceAll(",", "")));
    // 本期账单余额表头
    tableElements = doc.select("table[class=simple]");
    // 本期对账单表格内容
    var tds = tableElements.get(0).getElementsByTag("td");
    // 上期账单余额
    billAllData.setLastBalance(CreditResultUtil.StringToBigDecimal(tds.get(2).text().replaceAll(",", "")));
    // 本期实际还款
    // 本期新增款额
    var newCharges = CreditResultUtil.StringToBigDecimal(tds.get(6).text().replaceAll(",", ""));
    billAllData.setNewCharges(newCharges);
    // 本期新增账款tds.get(6).text()
    // 上期还款金额 ---页面无数据
    billAllData.setLastPayment(CreditResultUtil.StringToBigDecimal(tds.get(4).text().replaceAll(",", "")).negate());
    billAllData.setInterest(CreditResultUtil.StringToBigDecimal(tds.get(10).text().replaceAll(",", "")));// 循环利息
    var installments = new ArrayList();
    // 对账单分页处理
    parsePageData(billAllData, html, shopping_sheets, Installments, currency, card_num,year,month);

    billAllData.setShoppingSheets(shopping_sheets);
    billAllData.setInstallments(Installments);
}

/**
 * 未出账单
 * @param creditCardAllData
 * @param bills
 * @param card_num
 * @param j
 * @throws ClientProtocolException
 * @throws IOException
 * @throws DocumentException
 */
function getBillUndone(creditCardAllData, bills, card_num, j,undoneAndDoneBeforMap) {
    logger.info("{},抓取未出账单", context.get(LUA_TASK_KEY));
    var billAllData = new BillAllData();
    var shopping_sheets = new ArrayList();// 消费记录
    var Installments = new ArrayList();//分期记录

    var now = LocalDateTime.now();
    var year = now.getYear();
         year = Integer.parseInt(year);
    var  month =  now.getMonthValue();
         month = Integer.parseInt(month);
    var day =  now.getDayOfMonth();
        day = Integer.parseInt(day);

    var undoneMap = new HashMap();
        undoneMap.put("randomTokenVerifyTag",undoneAndDoneBeforMap.get("randomTokenVerifyTag"));
        undoneMap.put("verifyCodeBackUriTag",undoneAndDoneBeforMap.get("verifyCodeBackUriTag"));
        undoneMap.put("cardNo","1%7C2");
        undoneMap.put("queryStrDateYear",year);
        undoneMap.put("queryStrDateMonth",month);
        undoneMap.put("queryStrDateDay","01");
        undoneMap.put("db_current_time_year",year);
        undoneMap.put("db_current_time_month",month);
        undoneMap.put("db_current_time_day",day);
        undoneMap.put("queryEndDateYear",year);
        undoneMap.put("queryEndDateMonth",month);
        undoneMap.put("queryEndDateDay",day);
        undoneMap.put("db_current_time_year",year);
        undoneMap.put("db_current_time_month",month);
        undoneMap.put("db_current_time_day",day);
        undoneMap.put("queryMode","0");
        undoneMap.put("billYearMonYear",year);
        undoneMap.put("billYearMonMonth",month);

     var　html =  ajax_post(urls.BILLUNDONE_URL,undoneMap);
    storeDataToFile(context, html, j + "_unDonePage_1.html");

    billAllData.setBankName("华夏银行");
    billAllData.setBillId(UUID.randomUUID().toString());
    var installments = new ArrayList();
    billAllData.setInstallments(installments);
    var cld = Calendar.getInstance();
    var day = cld.get(Calendar.DAY_OF_MONTH);
    day = Integer.parseInt(day);
    if (StringUtils.isNotBlank(dateBill)) {
        if (day > Integer.parseInt(dateBill)) {
            cld.add(Calendar.MONTH, 1);
        }
    }
    var billdate = creditSdf.format(cld.getTime());
    billAllData.setBillMonth(billdate);
    if (StringUtils.isNotBlank(dateBill)) {
        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(billdate + "-" + dateBill));
    } else {
        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(billdate + "-05"));
    }
    billAllData.setBillType("UNDONE");

    var newcharges = new BigDecimal(0);
    // 以下数据页面无
    billAllData.setMinPayment(null);
    billAllData.setInterest(null);
    billAllData.setLastPayment(null);

    // 信用额度相关
    billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
    billAllData.setCashLimit(creditCardAllData.getCashLimit());
    // 美元相关---------先暂且设置为0
    billAllData.setUsdCashLimit(null);
    billAllData.setUsdCreditLimit(null);
    billAllData.setUsdInterest(null);
    billAllData.setUsdLastBalance(null);
    billAllData.setUsdLastPayment(null);
    billAllData.setUsdMinPayment(null);
    billAllData.setUsdNewBalance(null);
    billAllData.setUsdNewCharges(null);

    //这是上月的newBalance
    var lastBalance = context.get("newBalance");
    billAllData.setLastBalance((lastBalance !== "" && lastBalance !== null ) ? new BigDecimal(lastBalance) : null);

    var doc = Jsoup.parse(html);
    var export_xml = doc.select("span[class=export xml]");

    var sumMoney = 0.0;
    if (export_xml.size() != 0) {
        var span = export_xml.get(0);
        var downLoadUrl = span.parent().attr("href");
        logger.info("{},获取未出账单下载的 URL:{}",context.get(LUA_TASK_KEY) ,downLoadUrl);
        if (StringUtils.isNotBlank(downLoadUrl)) {
            var undoneXml = ajax_get("https://sbank.hxb.com.cn/" + downLoadUrl);
            storeDataToFile(context, undoneXml, j + "_unDonePage_1.xml");

              var  undoneDoc = Jsoup.parse(undoneXml);
                var rows =  undoneDoc.select("row");
                logger.info("{},未出账单有{}条数据",context.get(LUA_TASK_KEY),rows.size());
                for(var i = 0; i< rows.size(); i ++){
                    var  columns = rows.get(i).select("column");
                     var expense = new Expense();
                      expense.setId(UUID.randomUUID().toString());
                      expense.setOrderIndex(Long.parseLong(columns.get(0).text()));// 索引
                    // 交易时间
                    expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(columns.get(1).text() + " 00:00:00"));
                    expense.setPostDate(yyyy_MM_dd_PARSER.parse(columns.get(2).text()));
                    expense.setCardNum(columns.get(6).text());// 卡号后四位
                    expense.setCurrencyType(CreditResultUtil.convertCurr(columns.get(3).text()));// 交易币种

                    expense.setAmountMoney(CreditResultUtil.StringToBigDecimal(columns.get(5).text().replaceAll(",", "")));// 交易金额
                    logger.info("金额:------{}", columns.get(5).text());
                    sumMoney = sumMoney + Double.parseDouble(columns.get(5).text().replaceAll(",", ""));
                    if (expense.getAmountMoney().signum() == 1) {
                        newcharges = newcharges.add(expense.getAmountMoney());
                    }
                    expense.setCategory(CategoryUtil.getCreditCategory("HXB", columns.get(4).text(), expense.getAmountMoney().toString()));
                    expense.setDescription(columns.get(4).text());
                    expense.setBalance(null);
                    expense.setTransAddr("");
                    expense.setTransMethod("");
                    expense.setTransChannel("");
                    expense.setRemark("");
                    expense.setOppositeBank("");
                    expense.setNameOnOppositeCard("");
                    expense.setOppositeCardNo("");
                    shopping_sheets.add(expense);
                }
            billAllData.setNewCharges(newcharges);
        }
    }
    if (lastBalance !== "" && lastBalance !== null) {
        sumMoney = Double.parseDouble(lastBalance) + sumMoney;
    }
    billAllData.setNewBalance(new BigDecimal(String.format("%.2f", sumMoney)));
    billAllData.setShoppingSheets(shopping_sheets);
    billAllData.setInstallments(Installments);
    bills.add(billAllData);
}

/**
 * 信用卡额度和持卡人
 */
function parseUserInfo(html, creditCardAllData) {
    try {
        var doc = Jsoup.parse(html);
        var tableElements = doc.select("table[class=inputStyleTable]");
        for each(var el in tableElements){
            var tds = el.getElementsByTag("tr");
            creditCardAllData.setNameOnCard(tds.get(0).text().replaceAll("姓名", "").replaceAll("\\s*", "").trim());
            creditCardAllData.setCreditLimit(CreditResultUtil.StringToBigDecimal(tds.get(1).text().replaceAll("信用额度", "").trim().replaceAll(",", "")));
            creditCardAllData.setBalance(CreditResultUtil.StringToBigDecimal(tds.get(2).text().replaceAll("可用额度", "").trim().replaceAll(",", "")));
            creditCardAllData.setCashLimit(CreditResultUtil.StringToBigDecimal(tds.get(3).text().replaceAll("预借现金信用额度", "").trim().replaceAll(",", "")));
            creditCardAllData.setCashBalance(CreditResultUtil.StringToBigDecimal(tds.get(4).text().replaceAll("预借现金可用额度", "").trim().replaceAll(",", "")));
        }
    } catch (e) {
        logger.info("{},信用卡额度抓取异常:{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }

}


/**
 * 完整卡号和卡号后四位
 * @param html
 * @param creditCardAllData
 * @param map
 * @param j
 * @param card_num
 */
function parseCardInfo(html, creditCardAllData, j, card_num) {
    try {
        var fullCardNumList = new ArrayList();
        var doc = Jsoup.parse(html);
        var tableElement = doc.getElementById("accountDetailQueryDisplayVBList_row");
        var tbody = tableElement.select("tbody");
        var trs = tbody.select("tr");
        for (var i = 0; i < trs.size(); i++) {
            var tds = trs.get(i).select("td");
            var currentType = tds.get(4).text();
            if (equals(currentType, "华夏信用卡")) {
                // 卡号
                var fullCardNum = RegexUtils.GetText(tds.get(1).text(), "\\d*");
                fullCardNumList.add(fullCardNum);
                // if(fullCardNum.endsWith(card_num)){
                creditCardAllData.setFullCardNum(list2String(fullCardNumList));
                // 卡号后四位
                creditCardAllData.setCardNum(getCardNumList(fullCardNumList));
                // }
            }
        }
    } catch (e) {
        logger.info("{},信用卡卡号抓取异常:{}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
}

/**
 * 卡号后四位
 * @param cardNumList
 * @return
 */
function getCardNumList(cardNumList) {
    var sb = new StringBuffer();
    for each(var cardNum in cardNumList){
        sb.append(cardNum.substring((cardNum.length() - 4), (cardNum.length()))).append(",");
    }
    return sb.toString().trim().substring(0, sb.toString().length() - 1);
}

/**
 * 卡号集合
 * @param list
 * @return
 */
function list2String(list) {
    var sb = new StringBuffer();
    for each(var str in list){
        sb.append(str).append(",");
    }
    return sb.toString().trim().substring(0, sb.toString().length() - 1);
}


/**
 * 信用卡明细
 * @param billAllData
 * @param html
 * @param i
 * @param shopping_sheets
 * @param installments
 * @param currency
 * @param card_num
 */
function parsePageData(billAllData, html, shopping_sheets, installments, currency, card_num,year,month) {
    // 对账单明细表体
    logger.info("{} 开始解析{}年{}月", context.get(LUA_TASK_KEY),year,month);
    var doc = Jsoup.parse(html);
    var billDetailTds = doc.select("#pcreditTabQueryListRMB td");

        var exporDoneXml = doc.select("span[class=export xml]");
        if (exporDoneXml.size() != 0) {

            var unDoneSpan = exporDoneXml.get(0);
            var downLoadUrl = unDoneSpan.parent().attr("href");
            logger.info("{},获取已出账单下载的路径:{}", context.get(LUA_TASK_KEY),downLoadUrl);

            downLoadUrl = "https://sbank.hxb.com.cn" + downLoadUrl;
           if(StringUtils.isNotBlank(downLoadUrl)){
               var doneXml = ajax_get(downLoadUrl);
               storeDataToFile(context, doneXml, year + "-" + month + "shoppingExpense.xml");

               var doneXmlDoc = Jsoup.parse(doneXml);
               var rows =  doneXmlDoc.select("row");
               logger.info("{},{}年{}月，{}条数据",context.get(LUA_TASK_KEY),year,month,rows.size());
               for(var i = 0; i < rows.size(); i ++){
                   　　var row = rows.get(i);
                   var installment = new Installment();
                   var expense = new Expense();
                   var columns =  row.select("column");
                       expense.setOrderIndex(Long.parseLong(columns.get(0).text()));// 设置序号
                       //交易日期
                       expense.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(columns.get(1).text() + " 00:00:00"));
                       //记帐日期
                       expense.setPostDate(yyyy_MM_dd_PARSER.parse(columns.get(2).text()));
                       //描述
                       expense.setDescription(columns.get(3).text());
                       //金额
                       expense.setAmountMoney(CreditResultUtil.StringToBigDecimal(columns.get(4).text().replaceAll(",", "")));
                       //卡号
                       expense.setCardNum(columns.get(5).text());
                       expense.setId(UUID.randomUUID().toString());// 改为随机
                       expense.setCurrencyType(currency);// 币种
                       expense.setBalance(null);
                       expense.setTransAddr("");
                       expense.setTransMethod("");
                       expense.setTransChannel("");
                       expense.setRemark("");
                       expense.setOppositeBank("");
                       expense.setNameOnOppositeCard("");
                       expense.setOppositeCardNo("");
                       expense.setCategory(CategoryUtil.getCreditCategory("HXB", expense.getDescription(), expense.getAmountMoney().toString()));


                   if (expense.getDescription().contains("分期") && !expense.getDescription().contains("手续费") && !expense.getDescription().contains("转分期")) {
                       installment.setAmountMoney(expense.getAmountMoney());
                       installment.setShoppingsheetId(UUID.randomUUID().toString());
                       installment.setPostDate(expense.getPostDate());
                       installment.setTransDate(expense.getTransDate());
                       installment.setInstallmentDesc(expense.getDescription());
//						installment.setHandingFee(expense.getAmountMoney());
                       installment.setTransferFee(null);
                       installment.setInstallmentType(CreditResultUtil.installmentTypeChange(expense.getDescription()));
                       installment.setCurrencyType("CNY");
                       installment.setTransferfeeDesc("");
                       installment.setHandingfeeDesc("");
                       var bill = expense.getDescription();
                       var p = Pattern.compile("第(\\d+)期共(\\d+)期");
                       var m = p.matcher(bill);
                       if (m.find()) {
                           var month = Integer.parseInt(m.group(1));
                           var total = Integer.parseInt(m.group(2));
                           installment.setTotalMonth(total);
                           installment.setCurrentMonth(month);
                       }
                       installments.add(installment);
                   } else if (expense.getDescription().contains("手续费")) {
                       // 找到已经存在的分期
                       var targetInstallment = findExistInstallment(installments, expense.getDescription());
                       installment = targetInstallment !== null ? targetInstallment : new Installment();

                       installment.setHandingFee(expense.getAmountMoney());
                       installment.setHandingfeeDesc(expense.getDescription());
                   }
                   shopping_sheets.add(expense);

                   installment = new Installment();
               }
           }
        }
}


function findExistInstallment(installments, description) {
    // TODO Auto-generated method stub
    for each(var installment in installments){
        if (equals(installment.getInstallmentDesc().split(" ")[0], description.split(" ")[0]) && !installment.getInstallmentDesc().contains("手续费")) {
            return installment;
        }
    }
    return null;
}



var luaFuncs = {
    checkControlAvailable:function(){
        var map = new HashMap();
        map.put("method","checkControlAvailable");
        return sendAndReceive(map)
    },
    getHtml:function () {
        var map = new HashMap();
        map.put("method","getHtml");
        return sendAndReceive(map);
    },
    click_by_name: function () {
        var map = new LinkedHashMap();
        map.put("method", "click_by_name");
        //lp.Send(JSON.toJSONString(map));
        return sendAndReceive(map)
    },

    openLoginPage: function () {
        var map = new LinkedHashMap();
        map.put("method", "openLoginPage");
        return sendAndReceive(map)
    },

    inputUPAndGetOperationResult: function (username, password, type) {
        var map = new LinkedHashMap();
        map.put("method", "inputUPAndGetOperationResult");
        map.put("username", username);
        map.put("password", password);
        map.put("type", type);

        return sendAndReceive(map)
    },

    /**
     * 输入密码
     *
     * @param password
     * @return
     */
    input_password_hx: function (password) {
        var map = new LinkedHashMap();
        map.put("method", "input_password_hx");
        map.put("password", password);
        if (map.containsKey("password")) {
            map.put("password", "*******");
        }

        return sendAndReceive(map)
    },

    check_is_img: function () {
        var map = new LinkedHashMap();
        map.put("method", "check_is_img");
        return sendAndReceive(map)
    }
    /*,
     getLoginCookie:function() {
        var map = new LinkedHashMap();
        map.put("method", "getLoginCookie");
        return sendAndReceive(map);
}*/

}